using System.Collections;
using Game;
using Engine;
using System.Collections.Concurrent;
using System.Net.Http;
using System.Reflection.Metadata;
using System.Threading.Tasks;
using System.Xml.Linq;
using Engine.Graphics;
using GameEntitySystem;
using OpenTK.Input;
using TemplatesDatabase;

namespace StyleSurvivalcraft;
#region StyleTerrainGeneratedModloader
public class StyleTerrainGenerated : ModLoader
{
    public Game.Random m_random = new Game.Random();
    public SubsystemTerrain subsystemTerrain;
    public WorldSettings m_worldSettings;
    public SubsystemParticles m_subsystemParticles;
    public Terrain m_terrain;
    public TerrainChunk m_chunk;
    public ComponentGui m_gui;
    private const int MinTreeHeight = 66;
    private const int GrassBlockId = 8;
    private const int ChunkSize = 16;
    
    public override void __ModInitialize() 
    {
        ModsManager.RegisterHook("OnMinerHit", this);
        ModsManager.RegisterHook("OnProjectLoaded", this);
        ModsManager.RegisterHook("TerrainContentsGenerator24Initialize", this);
        ModsManager.RegisterHook("ChangeSkyColor", this);
        ModsManager.RegisterHook("SetShaderParameter", this);
    }
    public override void OnProjectLoaded(Project project)
    {
        m_subsystemParticles = project.FindSubsystem<SubsystemParticles>(throwOnError: true);
    }

    public override Color ChangeSkyColor(Color oldColor, Vector3 direction, float timeOfDay, int temperature)
    {
        // 基础色调 蓝
        float hue = 0.6f; 
        
        // 根据温度调整饱和度（-30°C到50°C映射0.7-0.3）
        float saturation = MathUtils.Clamp(0.7f - (temperature + 30) * 0.005f, 0.3f, 0.7f);
        
        // 根据昼夜亮度变化（午夜最暗）
        float lightness = 0.5f + 0.15f * MathF.Cos(timeOfDay * MathF.PI * 2);

        // 实现HSL到RGB的转换方法
        static Color HSLToRGB(float h, float s, float l)
        {
            h = MathUtils.Clamp(h, 0f, 1f);
            s = MathUtils.Clamp(s, 0f, 1f);
            l = MathUtils.Clamp(l, 0f, 1f);

            float r, g, b;
    
            if (s == 0f)
            {
                r = g = b = l;
            }
            else
            {
                float q = l < 0.5f ? l * (1f + s) : l + s - l * s;
                float p = 2f * l - q;
                r = HueToRGB(p, q, h + 1f/3f);
                g = HueToRGB(p, q, h);
                b = HueToRGB(p, q, h - 1f/3f);
            }
            return new Color(r * 255f, g * 255f, b * 255f);
        }

        static float HueToRGB(float p, float q, float t)
        {
            if (t < 0f) t += 1f;
            if (t > 1f) t -= 1f;
            if (t < 1f/6f) return p + (q - p) * 6f * t;
            if (t < 1f/2f) return q;
            if (t < 2f/3f) return p + (q - p) * (2f/3f - t) * 6f;
            return p;
        }

        // 转换为RGB颜色空间
        Color hslColor = HSLToRGB(hue, saturation, lightness);
        
        // 添加大气散射效果（面向太阳方向增强亮度）
        float scattering = MathUtils.Clamp(Vector3.Dot(direction, Vector3.UnitY) * 1.2f, 0.2f, 1.5f);
        return new Color(
            oldColor.R,
            oldColor.G,
            oldColor.B,
            oldColor.A
        );
    }

    public override void SetShaderParameter(Shader shader, Camera camera)
    {
    }

    public override void TerrainContentsGenerator24Initialize(ITerrainContentsGenerator terrainContentsGenerator, SubsystemTerrain subsystemTerrain)
    {
        if (terrainContentsGenerator is TerrainContentsGenerator24 generator24)
        {
            generator24.ChunkGenerationStep4.Add(new ChunkGenerationStep(196,CreateCherryBlossomTree));
        }
    }
    public override void OnMinerHit(ComponentMiner miner, ComponentBody componentBody, Vector3 hitPoint, Vector3 hitDirection, ref float attackPower, ref float playerProbability, ref float creatureProbability, out bool Hitted)
    {
        Hitted = false;
        if (componentBody?.Entity == null) return; 
        
        IInventory inventory = miner.Inventory;
        int activeBlockValue = miner.ActiveBlockValue;
        int blockIndex = Terrain.ExtractContents(activeBlockValue);
        
        var creatureComponent = componentBody.Entity.FindComponent<ComponentCreature>();
        if (creatureComponent == null) return;

        switch (blockIndex)
        {
            case var idx when idx == BlocksManager.GetBlockIndex<StyleWeapons.Ice_Sword>():
                HandleIceSwordEffects(hitPoint, creatureComponent);
                break;
            case var idx when idx == BlocksManager.GetBlockIndex<StyleWeapons.Fire_Sword>():
                HandleFireSwordEffects(componentBody.Entity, hitPoint, creatureComponent);
                break;
            case var idx when idx == BlocksManager.GetBlockIndex<StyleWeapons.Entity_Copy_Stone>():
                miner.ComponentPlayer?.ComponentGui?.DisplaySmallMessage("功能未写", Color.White, false, false);
                break;
        }
    }

    private void HandleIceSwordEffects(Vector3 hitPoint, ComponentCreature creature)
    {
        m_subsystemParticles.AddParticleSystem(new FireworksParticleSystem(hitPoint, Color.Blue, FireworksBlock.Shape.SmallBurst, 0.3f, 0.5f));
        m_subsystemParticles.AddParticleSystem(new HitValueParticleSystem(hitPoint + new Vector3(0, 0.5f, 0), new Vector3(0, 0.5f, 0), Color.LightBlue, "减速"));
        creature.ComponentLocomotion.WalkSpeed = 1f;
    }

    private void HandleFireSwordEffects(Entity entity, Vector3 hitPoint, ComponentCreature creature)
    {
        var onFire = entity.FindComponent<ComponentOnFire>();
        if (onFire == null) return;

        m_subsystemParticles.AddParticleSystem(new FireworksParticleSystem(hitPoint, Color.Red, FireworksBlock.Shape.SmallBurst, 0.3f, 0.5f));
        m_subsystemParticles.AddParticleSystem(new HitValueParticleSystem(hitPoint + new Vector3(0, 0.5f, 0), new Vector3(0, 0.5f, 0), Color.Red, "燃烧"));
        onFire.SetOnFire(creature, m_random.Float(6f, 8f));
    }

    public static void CreateCherryBlossomTree(TerrainChunk chunk)
    {
        var terrain = chunk.Terrain;
        var random = new Game.Random(chunk.Coords.X + 101 * chunk.Coords.Y);
        var origin = chunk.Origin;

        // 预计算区块坐标范围
        int startX = origin.X;
        int startZ = origin.Y;
        int endX = startX + ChunkSize;
        int endZ = startZ + ChunkSize;

        for (int cx = startX; cx < endX; cx++)
        {
            for (int cz = startZ; cz < endZ; cz++)
            {
                int surfaceHeight = terrain.CalculateTopmostCellHeight(cx, cz);
                if (!IsValidPosition(terrain, cx, cz, surfaceHeight)) continue;

                GenerateTree(chunk, terrain, random, cx, cz, surfaceHeight);
            }
        }
    }

    private static bool IsValidPosition(Terrain terrain, int x, int z, int height)
    {
        if (height < MinTreeHeight) return false;
        if (terrain.GetCellContentsFast(x, height, z) != GrassBlockId) return false;
        
        // 使用位掩码检查四个方向（北东南西）
        int collisionMask = 0;
        collisionMask |= (BlocksManager.Blocks[terrain.GetCellContentsFast(x + 1, height, z)].IsCollidable ? 1 : 0) << 0;
        collisionMask |= (BlocksManager.Blocks[terrain.GetCellContentsFast(x - 1, height, z)].IsCollidable ? 1 : 0) << 1;
        collisionMask |= (BlocksManager.Blocks[terrain.GetCellContentsFast(x, height, z + 1)].IsCollidable ? 1 : 0) << 2;
        collisionMask |= (BlocksManager.Blocks[terrain.GetCellContentsFast(x, height, z - 1)].IsCollidable ? 1 : 0) << 3;

        return collisionMask == 0; // 所有方向都不可碰撞
    }

    private static void GenerateTree(TerrainChunk chunk, Terrain terrain, Game.Random random, 
        int worldX, int worldZ, int surfaceHeight)
    {
        const float treeSize = 5f;
        var brush = CreateCherryBlossomTreeBrush_Original(random, treeSize, new Point3(worldX, surfaceHeight, worldZ));
        
        foreach (var cell in brush.Cells)
        {
            int cellWorldX = worldX + cell.X;
            int cellWorldZ = worldZ + cell.Z;
            int y = surfaceHeight + cell.Y;

            // 转换为区块局部坐标
            int localX = cellWorldX - chunk.Origin.X;
            int localZ = cellWorldZ - chunk.Origin.Y;

            if (localX >= 0 && localX < ChunkSize && 
                localZ >= 0 && localZ < ChunkSize && 
                y is >= 0 and < 256)
            {
                chunk.SetCellValueFast(localX, y, localZ, cell.Value);
            }
        }
    }
    

    #region 樱花树刷子
    private static TerrainBrush CreateCherryBlossomTreeBrush_Original(Game.Random random, float size, Point3 basePoint)
    {
        int height = 5;//树干高度
        TerrainBrush terrainBrush = new TerrainBrush(); //创建一个新的地形刷子对象。
        int value = BlocksManager.GetBlockIndex<StyleSakuraBlock>(); 
        int value2 = BlocksManager.GetBlockIndex<StyleSakuraLeavesBlock>(); 
        //向地形刷子添加一条射线，用于生成樱花树的树干。射线的起点是(0, -1, 0)，终点是(0, 8, 0)，宽度为2，高度为2，深度为2，方块类型为树干方块类型。
        terrainBrush.AddRay(0, -1, 0, 0, height, 0, 1, 1, 1, value);
        List<Point3> list = new List<Point3>(); //创建一个列表，用于存储树枝生成的位置信息。
        float num = random.Float(0f, 6.2831855f); //生成一个随机的浮点数作为角度值，用于计算树枝的方向。
        for (int i = 0; i < 6; i++) //迭代3次，生成3个树枝
        {
            float radians = num + (float)i * MathUtils.DegToRad(120f); //计算当前树枝的角度，根据角度的增量120°来确定每个树枝之间的角度差。
            Vector3 v = Vector3.Transform(Vector3.Normalize(new Vector3(1f, random.Float(1f, 1.5f), 0f)), Matrix.CreateRotationY(radians)); //根据角度和随机生成的长度因子，计算树枝的方向向量。
            int num2 = random.Int((int)(0.7 * size), (int)(1.2 * size));  //树枝的长度由(int)(0.7f * size)和(int)size之间的随机整数决定。
            Point3 point = new Point3(0, height - 1, 0);   //树枝生成的起始位置
            Point3 point2 = new Point3(Vector3.Round(new Vector3(point) + v * (float)num2)); //根据起始位置、方向向量和长度计算树枝的结束位置。
            terrainBrush.AddRay(point.X, point.Y, point.Z, point2.X, point2.Y, point2.Z, 1, 1, 1, value); //向地形刷子添加一条射线，用于生成树枝。射线的起点是起始位置，终点是结束位置，宽度为1，高度为1，深度为1，方块类型为树干方块类型。
            list.Add(point2); //将树枝的结束位置添加到列表中，用于后续生成树枝周围的树叶。
        }
        foreach (Point3 point3 in list) //遍历存储树枝位置的列表。
        {
            float num3 = random.Float(0.45f * size, 0.6f * size); // 随机生成树叶的大小，大小范围为0.45倍到0.6倍的size值。
            int num4 = (int)MathUtils.Ceiling(num3); // 向上取整树叶的大小，得到树叶的半径。
            int trunkHeight = height; // 树枝的高度
            int maxHeight = point3.Y + trunkHeight + num4; // 树叶生成的最大高度限制为树枝高度加树叶半径

            for (int j = point3.X - num4; j <= point3.X + num4; j++) // 遍历树叶周围的X坐标范围。
            {
                for (int k = point3.Y; k <= maxHeight; k++) // 遍历树叶的高度范围，从树枝顶部到最大高度。
                {
                    for (int l = point3.Z - num4; l <= point3.Z + num4; l++) // 遍历树叶周围的Z坐标范围。
                    {
                        int num5 = MathUtils.Abs(j - point3.X) + MathUtils.Abs(l - point3.Z); // 计算当前位置与树叶起始位置的Manhattan距离。
                                                                                              // 计算当前位置与树叶起始位置的欧几里得距离，使用缩放因子(1, 1.7, 1)来调整距离。
                        float num6 = ((new Vector3((float)j, (float)k, (float)l) - new Vector3(point3)) * new Vector3(1f, 1.7f, 1f)).Length();
                        // 判断当前位置是否满足生成树叶的条件：距离树叶起始位置距离小于等于树叶大小、距离树叶起始位置的Manhattan距离小于等于树叶半径。
                        if (num6 <= num3 && num5 <= num4 && terrainBrush.GetValue(j, k, l) == null)
                        {
                            terrainBrush.AddCell(j, k, l, value2); // 生成树叶
                        }
                    }
                }
            }
        }

        terrainBrush.Compile();
        return terrainBrush;
    }
    #endregion 樱花树刷子
}
#endregion StyleTerrainGeneratedModloader
#region StyleOnLoadingFinishedModloader

public class StyleOnLoadingFinishedModloader : ModLoader
{
    public override void __ModInitialize()
    {
        ModsManager.RegisterHook("BeforeGameLoading", this);
    }
    
    private BevelledButtonWidget StyleUpdate = new BevelledButtonWidget()
    {
        
        Name = "StyleUpdate",
        Style = ContentManager.Get<XElement>("Styles/ButtonStyle_310x60"),
        HorizontalAlignment = WidgetAlignment.Near,
        VerticalAlignment = WidgetAlignment.Near,
    };
    
    public override void OnLoadingFinished(List<Action> actions)
    {
        SettingsScreen settings = ScreensManager.FindScreen<SettingsScreen>("Settings");
        StackPanelWidget stackPanelWidget = (StackPanelWidget)settings.Children.Find<BevelledButtonWidget>("Performance", true).ParentWidget;
        stackPanelWidget.AddChildren(StyleUpdate);
        if (StyleUpdate != null)
        {
            StyleUpdate.Text = "AI小贴士(联网)";
        }
        stackPanelWidget.Update1 += delegate
        {
            stackPanelWidget.Update();
            if (StyleUpdate.IsClicked)
            {
                StyleSurvivalcraft.StyleUpdate.ShowUpdate();
            }
        };
        
        actions.Add(delegate
        {
            CraftingRecipe craftingRecipe = new CraftingRecipe();//创建合成
            craftingRecipe.Ingredients = new string[9] { null, "experience", null, "experience", "diamond", "experience", null, "experience", null };
            craftingRecipe.ResultValue = BlocksManager.GetBlockIndex<StyleCrossBlock>();//合成出的物品id
            craftingRecipe.ResultCount = 1;//数量
            craftingRecipe.RemainsValue = 0;//副产物id
            craftingRecipe.RemainsCount = 0;//副产物数量
            craftingRecipe.RequiredHeatLevel = 0;//所需合成等级，0为合成台，1为熔炉
            craftingRecipe.RequiredPlayerLevel = 3;//所需玩家等级
            CraftingRecipesManager.m_recipes.Add(craftingRecipe);//添加这个合成
        });
        
        string newcr = ContentManager.Get<string>("new", ".stylecr");
        string[] logLines = newcr.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
        
        // 跳过第一行的读取
        if (logLines.Length > 0)
        {
            logLines = logLines.Skip(1).ToArray();
        }
        
        foreach (string line in logLines)
        {
            string[] parts = line.Split('|');
            if (parts.Length >= 18)
            {
                try
                {
                    //调用外部文件，还没想好干啥
                }
                catch (Exception e)
                {
                    Log.Error($"Error parsing block data: {e.Message}");
                }
            }
        }

        Task.Run(async () =>
        {
            using (var client = new HttpClient())
            {
                try
                {
                    string urlContent = await client.GetStringAsync("https://gitee.com/yang-zhengping-1/miscellaneous-items/raw/master/cs.txt");
                    string[] urlLogLines = urlContent.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string line in urlLogLines)
                    {
                        Log.Information(line);
                    }
                }
                catch (HttpRequestException e)
                {
                    Log.Error($"Request error: {e.Message}");
                }
                catch (Exception e)
                {
                    Log.Error($"An error occurred: {e.Message}");
                }
            }
        }).Wait();
    }
}
#endregion StyleOnLoadingFinishedModloader